package cn.htsyb.synergy.tester.adapter;

import cn.htsyb.synergy.tester.config.InitConfig;
import cn.htsyb.synergy.tester.model.CaseBean;
import cn.htsyb.synergy.tester.model.OperateBean;
import cn.htsyb.synergy.utils.ResourceUtil;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class JsonAdapter extends InitConfig implements IAdapter {
    private final static String JSONENDSWITH = ".json";
    private static final Log defLog = LogFactory.getLog(JsonAdapter.class);
    private static String testCasePath;
    private static String elementPath;
    private static String ParamPath;
    private static String operatePath;
    private static String adapterType;


    public static String getAdapterType() {
        adapterType = null == adapterType ? synertestConfig.getString("runner[@adapter]").trim() : adapterType;
        return adapterType;
    }

    public static String getTestCasePath() {
        testCasePath = testCasePath == null ? synertestConfig.getString("runner." + getAdapterType() + ".testCasePath")
                : testCasePath;
        return ResourceUtil.convertToLocalPath(testCasePath);
    }

    public static String getElementPath() {
        elementPath = null == elementPath ? synertestConfig.getString("runner." + getAdapterType() + ".elementPath")
                : elementPath;
        return ResourceUtil.convertToLocalPath(elementPath);
    }

    public static String getParamPath() {
        ParamPath = null == ParamPath ? synertestConfig.getString("runner." + getAdapterType() + ".ParamPath")
                : ParamPath;
        return ResourceUtil.convertToLocalPath(ParamPath);
    }

    public static String getOperatePath() {
        operatePath = null == operatePath ? synertestConfig.getString("runner." + getAdapterType() + ".operatePath")
                : operatePath;
        return ResourceUtil.convertToLocalPath(operatePath);
    }

    private static File[] listFile(String filePath, final String fileEndsWith) {
        defLog.debug("根据路径" + filePath + "列出其下所有后缀名为" + fileEndsWith + "的文件");
        if (filePath == null) {
            return new File[0];
        }
        File filePathObj = new File(filePath);
        if (!filePathObj.exists()) {
            defLog.info("路径" + filePath + "不存在，返回空列表");
            return new File[0];
        } else if (filePath.endsWith(fileEndsWith)) {
            defLog.debug("路径" + filePath + "即是后缀名即为" + fileEndsWith + "的文件");
            return new File[]{filePathObj};
        }
        return filePathObj.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File fileObj, String fileName) {
                if (fileName.endsWith(fileEndsWith)) {
                    defLog.debug("判断文件" + fileName + "符合后缀名为" + fileEndsWith + "的");
                    return true;
                }
                return false;
            }
        });
    }

    @Override
    public TreeMap<String, OperateBean> loadOperate() throws Exception {
        TreeMap<String, OperateBean> OperateBeanMap = new TreeMap<String, OperateBean>();
        File[] jsonFile = listFile(getOperatePath(), JSONENDSWITH);
        defLog.info("获取路径" + getOperatePath() + "下后缀名为" + JSONENDSWITH + "的Operate文件共" + jsonFile.length
                + "个");
        for (File fileObj : jsonFile) {
            String jsonStr = FileUtils.readFileToString(fileObj, InitConfig.getLocalCoding());
            JsonArray operateArray = (new JsonParser()).parse(jsonStr).getAsJsonArray();
            for (JsonElement jsonElement : operateArray) {
                OperateBean operateBean = (new Gson()).fromJson(jsonElement, OperateBean.class);
                OperateBeanMap.put(operateBean.getOperate(), operateBean);
            }
        }
        return OperateBeanMap;
    }

    @Override
    public Map<String, String> loadElement() throws Exception {
        Map<String, String> elementMap = new HashMap<String, String>();
        File[] jsonFile = listFile(getElementPath(), JSONENDSWITH);
        defLog.info("获取路径" + getTestCasePath() + "下后缀名为" + JSONENDSWITH + "的Element文件共" + jsonFile.length
                + "个");
        for (File fileObj : jsonFile) {
            String jsonStr = FileUtils.readFileToString(fileObj, InitConfig.getLocalCoding());
            elementMap.putAll((new Gson()).fromJson(jsonStr, HashMap.class));
        }
        return elementMap;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> loadParam() throws IOException {
        Map<String, Object> globalParamMap = new HashMap<String, Object>();
        File[] jsonFile = listFile(getParamPath(), JSONENDSWITH);
        for (File fileObj : jsonFile) {
            String jsonStr = FileUtils.readFileToString(fileObj, InitConfig.getLocalCoding());
            globalParamMap.putAll((new Gson()).fromJson(jsonStr, HashMap.class));
        }
        return globalParamMap;
    }

    @Override
    public ArrayList<CaseBean> loadTestCase() throws Exception {
        ArrayList<CaseBean> caseList = new ArrayList<CaseBean>();
        File[] jsonFile = listFile(getTestCasePath(), JSONENDSWITH);
        defLog.info("获取路径" + getTestCasePath() + "下后缀名为" + JSONENDSWITH + "的TestCase文件共" + jsonFile.length
                + "个");
        for (File fileObj : jsonFile) {
            String jsonStr = FileUtils.readFileToString(fileObj, InitConfig.getLocalCoding());

            caseList.addAll(parasJsonToCase(jsonStr));

        }
        return caseList;
    }

    public ArrayList<CaseBean> parasJsonToCase(String jsonStr) {
        ArrayList<CaseBean> caseList = new ArrayList<CaseBean>();
        JsonElement caseJsonEle = (new Gson()).toJsonTree(jsonStr);
        if (caseJsonEle.isJsonArray()) {
            for (JsonElement caseJson : caseJsonEle.getAsJsonArray()) {
                CaseBean caseBean = (new Gson()).fromJson(caseJson, CaseBean.class);
                caseList.add(caseBean);
            }
        } else {
            CaseBean caseBean = (new Gson()).fromJson(jsonStr, CaseBean.class);
            defLog.info("解析case：" + caseBean.getDescribe());
            caseList.add(caseBean);
        }
        return caseList;
    }

    @Override
    public TreeMap<String, CaseBean> loadCommCase() throws Exception {
        TreeMap<String, CaseBean> caseMap = new TreeMap<String, CaseBean>();
        File[] jsonFile = listFile(getTestCasePath(), JSONENDSWITH);
        defLog.info("获取路径" + getTestCasePath() + "下后缀名为" + JSONENDSWITH + "的TestCase文件共" + jsonFile.length
                + "个");
        for (File fileObj : jsonFile) {
            String jsonStr = FileUtils.readFileToString(fileObj, InitConfig.getLocalCoding());
            CaseBean caseBean = (new Gson()).fromJson(jsonStr, CaseBean.class);
            defLog.info("解析case：" + caseBean.getDescribe());
            if (caseMap.get(caseBean.getDescribe()) != null) {
                defLog.warn("解析到同名用例[" + caseBean.getDescribe() + "]");
            }
            caseMap.put(caseBean.getDescribe(), caseBean);
        }
        return caseMap;
    }
}
